<?php

require_once dirname(__FILE__).'/AIS_DocCommentTagImpl.php';
/**
 * This class represents a Doc Comment
 */
class AIS_DocComment
{
	/**
	 * Constructs a new AIS_DocComment from the given text
	 * 
	 * @param string $text
	 */
	public function __construct($text)
	{
		$array = preg_split("/\n/",$text);
		$commentReading = true;
		foreach ($array as $line)
		{
			$line = trim(ereg_replace("^( |\t|/|\\*)*", "", $line));
			if (ereg("^@", $line))
			{
				$commentReading = false;
				$tag = $this->processTagLine($line, strtok($line," \t"));
				if ($tag)
				{
					if (!isset($this->tags[$tag->getName()]))
					{
						$this->tags[$tag->getName()] = array();
					}
					array_push($this->tags[$tag->getName()],$tag);
				}
				
			}
			else
			{
				if ($commentReading)
				{
					$this->comment .= trim($line)."\n";
				}
				
			}
		}
		
		$this->fillRestrictionsInVar();
		
		$this->comment = trim($this->comment);
	}
	/**
	 * 
	 * @return AIS_DocCommentTag
	 * @param string $line Line with tag
	 */
	protected function processTagLine($line, $name)
	{
		$className = isset(AIS_DocComment::$tagsClasses[$name])?AIS_DocComment::$tagsClasses[$name]:null;
		$tag = null;
		if ($className)
		{
			$tag = $this->$className($line, $name);
		}
		else
		{
			$nrOfValues = isset(AIS_DocComment::$commonTags[$name])? AIS_DocComment::$commonTags[$name] + 1 : 1;
			$tag = new AIS_DocCommentTagImpl($line, $nrOfValues);
		}
		return $tag;
	}
	
	private static $commonTags = array(
		'@param' => 2
	);
	
	/**
	 * Fills all restrictions to the attribute variable described with @var
	 *
	 */
	protected function fillRestrictionsInVar()
	{
		$tags = $this->getTags('@var');
		$tag = $tags[0];
		if ($tag)
		{
		foreach ($this->restrictions as $value)
		{
			$tag->addRestriction($value);
		}
		$tag->finishRestrictions();
		}
	}
	
	protected static $tagsClasses = array(
		'@var' => 'createVarTag',
		'@default' => 'createRestrictionTag',
		'@maximum' => 'createRestrictionTag',
		'@minimum' => 'createRestrictionTag',
		'@minItems' => 'createRestrictionTag',
		'@maxItems' => 'createRestrictionTag',
		'@pattern' => 'createRestrictionTag',
		'@maxLength' => 'createRestrictionTag',
		'@minLength' => 'createRestrictionTag',
		'@optional' => 'createRestrictionTag'
	);
	
	private function createVarTag($line, $name)
	{
		
		return new AIS_DocCommentTagParamWithRestrictions($line, 2);
	}
	
	protected function createRestrictionTag($line, $name)
	{
		$tag = new AIS_DocCommentTagJsonRestriction($name, strtok(" \t"));
		$this->restrictions[$name] = $tag;
	}
	
	/**
	 * Enter description here...
	 *
	 * @var AIS_DocCommentTagJsonRestriction[]
	 */
	private $restrictions = array();
	
	/**
	 * @var string
	 */
	private $comment = "";
	/**
	 * @var array
	 */
	private $tags = array();
	/**
	 * the comment of this DocComment
	 * @return string
	 */
	public function getComment()
	{
		return $this->comment;
	}
	/**
	 * 
	 * @return string[]
	 */
	public function getTagNames()
	{
		return array_keys($this->tags);
	}
	/**
	 * 
	 * @return AIS_DocCommentTag[]
	 * @param string $name Name of the tags to returns
	 */
	public function getTags($name)
	{
		return isset($this->tags[$name])?$this->tags[$name]:null;
	}
	/**
	 * 
	 * @return AIS_DocCommentTag
	 * @param string $name
	 */
	public function getTag($name)
	{
		$tags = $this->tags[$name];
		if ($tags)
		{
			return $tags[0];
		}
		return null;
	}
	/**
	 * Returns the type an array type contains
	 *
	 * @param $type string
	 * @return string
	 * 
	 */
	public static function getArrayType($type)
	{
		$len = strlen($type);
		return substr($type,0,$len-2);
	}
	/**
	 * Checks if given type is an array
	 *
	 * @param string $type
	 * @return boolean
	 */
	public static function isArray($type)
	{
		return stripos($type,"[") != 0;
	}
}

?>